package com.jpruby.handler.resolver;

import com.jpruby.annotation.CurrentUserId;
import com.jpruby.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

/**
 * 　　┏┓　　　┏┓+ +
 * 　┏┛┻━━━┛┻┓ + +
 * 　┃　　　　　　　┃
 * 　┃　　　━　　　┃ ++ + + +
 * ████━████ ┃+
 * 　┃　　　　　　　┃ +
 * 　┃　　　┻　　　┃
 * 　┃　　　　　　　┃ + +
 * 　┗━┓　　　┏━┛
 * 　　　┃　　　┃
 * 　　　┃　　　┃ + + + +
 * 　　　┃　　　┃    草泥马登场
 * 　　　┃　　　┃ +  神兽保佑
 * 　　　┃　　　┃    代码无bug
 * 　　　┃　　　┃　　+
 * 　　　┃　 　　┗━━━┓ + +
 * 　　　┃ 　　　　　　　┣┓
 * 　　　┃ 　　　　　　　┏┛
 * 　　　┗┓┓┏━┳┓┏┛ + + + +
 * 　　　　┃┫┫　┃┫┫
 * 　　　　┗┻┛　┗┻┛+ + + +
 * Created with IntelliJ IDEA.
 * Project: demo
 * Author: jpruby
 * Date: 2022/04/25/15:36
 * Description: 一看就会，一写就废
 * FilePath: com.jpruby.handler.resolver
 * HandlerMethodArgumentResolver 是spring的一个处理器 还有设置config
 * Copyright (c) 2022, All Rights Reserved.
 */

@Component
public class UserIdArgumentResolver implements HandlerMethodArgumentResolver {
    // 判断方法参数能使用当前的参数解析器，进行处理，自己要需要定义一个注解
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        // 如果方法参数含有@CurrentUserId 就能被我自定义的注解解析器解析
        return parameter.hasParameterAnnotation(CurrentUserId.class);
    }

    // 真正的参数解析的方法，可以在方法中获取对应的数据，然后把数据作为返回值返回，方法的返回值就会赋值给对应的方法参数
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        // 获取请求头中的token
        String token = webRequest.getHeader("token");
        // 解析token
        if (StringUtils.hasText(token)) {
            Claims claims = JwtUtil.parseJWT(token); // 如果解析不到也会被我的全局异常捕获
            return claims.getSubject();
        }
        return null;
    }
}
